package com.sky.interceptor;


import cn.hutool.http.HttpStatus;
import cn.hutool.http.server.HttpServerRequest;
import com.sky.context.BaseContext;
import com.sky.properties.JwtProperties;
import com.sky.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 用户拦截器(拦截器想要生效，需要注册拦截器)
 * 登录流程：前端发送请求  → 后端，后端调用小程序，获取openId   →   小程序
 * 后端存openId,生成token -> 发送给前端   ->前端存token并携带token 访问后端数据（进行购买、查询。。。）
 * <p>
 * 用户信息在token中 每个请求都要解析token很麻烦 就在拦截器中统一处理
 * 拦截器就是获取用户token 解析出来uuid/openId 放在线程中 在任何地方都可以取到
 */
@Slf4j
@Component
public class JwtTokenUserInterceptor implements HandlerInterceptor {

    //注入 获取token
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 拦截器 解析
     * @param request current HTTP request
     * @param response current HTTP response
     * @param handler chosen handler to execute, for type and/or instance evaluation
     * @return
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        log.info("用户拦截器启动");
        //获取前端用户请求 传入的token  (在请求头中)
        try {
            log.info("开始获取token: {}",jwtProperties.getUserTokenName());
            String token = request.getHeader(jwtProperties.getUserTokenName());  //约定token放在什么地方的
            log.info(token);
            if (!StringUtils.hasText(token)) {
                //返回 常量401
                response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
                log.info("获取用户token失败");
                return false;
            }
            //解析token
            Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
            log.info("解析结果{}", claims);
            Object userId = claims.get("userId");
            long userIdLong = Long.parseLong(userId.toString());
            BaseContext.setCurrentId(userIdLong);
            log.info("当前用户id为：{}", BaseContext.getCurrentId());

        } catch (Exception e) {
            log.info("解析token异常", e);  //很重要 预防找不到问题
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);//解析异常返回401
            return false;
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("用户拦截器销毁:{}",BaseContext.getCurrentId());
        BaseContext.removeCurrentId();
    }
}